﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Web.UI.HtmlControls;
using System.Xml;
using Metodesa.Logic;
using Metodesa.Tools;
using METODESA.Server.Data.Exceptions;
using METODESA.Server.Data.METODESA.Entity;
using METODESA.Server.Data.METODESA.Nhibernate;
using NHibernate;

namespace Metodesa.Views.Home
{

    public partial class ListProducto : System.Web.UI.Page
    {
        
        protected void Page_Load(object sender, EventArgs e)
        {

            if (ValidatorPrecio1.ValidationExpression.Equals(""))
            {
                loadExpressions();
            }
            if (ValidatorPrecio1.ErrorMessage.Equals(""))
            {
                loadMessages();
            }

            label.Visible = false;      // Hago invisible la etiqueta de informacion
            ListProductos.Visible = false;       // Hago invisibles todos los paneles extras
            PanelAddProducto.Visible = false;
            PanelEditProducto.Visible = false;
            if (Session["User"] != null)
            {
                Empleado usuario = (Empleado)Session["User"];
            }
            else
            {   // Si no existe una session redirecciono al Index
                Response.Redirect("../../Views/Home/Index.aspx", true); 
            }

            int ids = -1;


            String action = Request.QueryString.Get("a");
            if (action != null)
            {

                if (action.Equals("s")) // Select for update
                {
                    prepareDetailsUpdate();  //Preparo el panel para hacer Update
                }

                else if (action.Equals("d"))
                {
                    // DELETE
                    delete();
                }
            }
            
        }




        /// <summary>
        /// Procedimiento para cargar los mensajes del XML
        /// </summary>
        private void loadMessages()
        {
            XmlDocument xDoc = new XmlDocument();
            string path = Path.Combine(Server.MapPath("~"), @"Messages.xml");
            xDoc.Load(path);

            XmlNodeList lista = xDoc.GetElementsByTagName("message");
            foreach (XmlElement element in lista)
            {
                if (element.GetAttribute("name").Equals("formatoPrecio"))
                {
                    ValidatorPrecio1.ErrorMessage = element.GetAttribute("error");
                    ValidatorPrecio2.ErrorMessage = element.GetAttribute("error");
                }

            }

        }

        /// <summary>
        /// Procedimiento para cargar las expresiones regulares del XML
        /// </summary>
        private void loadExpressions()
        {
            XmlDocument xDoc = new XmlDocument();
            string path = Path.Combine(Server.MapPath("~"), @"Validations.xml");
            xDoc.Load(path);

            XmlNodeList lista = xDoc.GetElementsByTagName("validation");
            foreach (XmlElement element in lista)
            {
                if (element.GetAttribute("name").Equals("precio"))
                {
                    ValidatorPrecio1.ValidationExpression = element.GetAttribute("expression");
                    ValidatorPrecio2.ValidationExpression = element.GetAttribute("expression");
                }

            }

        }



        private void prepareDetailsUpdate()
        {
            int ids;
            Producto producto = null;
            if (int.TryParse(Request.QueryString.Get("id"), out ids))
            {
                producto = ProductoDao.getProductoById(ids);
            }
            
            if (producto!=null)
            {
                PanelEditProducto.Visible = true; // Hacer Visible el panel de detalles
                teId.Text = ids.ToString();
                teName.Text = producto.Nombre;
                teCategory.Text = producto.Categoria;
                tePrice.Text = producto.Precio.ToString();

            }
            else
            {
                label.Visible = true;
                label.ForeColor = Color.DarkRed;
                label.Text = "El producto no existe";
            }

        }
        
        private void delete()
        {
            try // Intento borrar 
            {
                int ids = int.Parse(Request.QueryString.Get("id"));
                ProductoLogic.delete(ids);
                label.Visible = true; // Si llega hasta aqui lo borre y escribo el mensaje
                label.ForeColor = Color.Blue;
                label.Text = "Producto eliminado satifactoriamente";
            }
            catch (EntityCouldntBeDeleted exception) // Si no se borro 
            {
                label.Visible = true;
                label.ForeColor = Color.Red;
                label.Text = exception.Message;
                Session.Add("Error", exception); // Coloco el mensaje que me trae la excepcion
            }
            catch (HibernateException exception)
            {
                label.Visible = true;
                label.ForeColor = Color.Red;
                label.Text = "Producto no se puede borrar"; // Error con el nHibernate no pude borrar
                Session.Add("Error", exception);
            }
            catch (Exception exception)
            {
                Session.Add("Error", exception); // Cualquier otra excepcion voy a la pagina del error
                Response.Redirect("../../Views/Home/Error.aspx", true);
            }
        }

        private void PrepareDetailsAdd()
        {
            ListProductos.Visible = false;
            PanelAddProducto.Visible = true;


            taName.Text = "";
            taCategory.Text = "";
            taName.Text = "";
            taPrice.Text = "";
        }

        private void EditProducto()
        {
         try
         {

             ProductoLogic.update(int.Parse(teId.Text), double.Parse(tePrice.Text), teCategory.Text, teName.Text);

              label.Visible = true;
              label.ForeColor = Color.Blue;
              label.Text = "Producto mofificado satifactoriamente";
         }
         #region manejo de errores
         catch (FormatException exception)
            {
                Session.Add("Error", exception);
                label.Visible = true;
                label.ForeColor = Color.DarkRed;
                label.Text = "Precio no valido";
                PanelEditProducto.Visible = true;

            }
            catch(EntityCouldntBeUpdated exception)
            {
                Session.Add("Error", exception);
                label.Visible = true;
                label.ForeColor = Color.Red;
                label.Text = "No se pudo modificar el producto";
                PanelEditProducto.Visible = true;
                
            }
             catch (Exception exception)
             {
                 Session.Add("Error", exception);
                 Response.Redirect("../../Views/Home/Error.aspx", true);


             }

            #endregion



        }

        // Funcion que se llama para las busquedas
        protected void FindButton_Click(object sender, EventArgs e)
        {
            IList<Producto> lista;
            if (option != null && option.SelectedItem != null)
                lista = ProductoLogic.processSearch(searchbox.Text, option.SelectedValue);
            else
                lista = ProductoLogic.processSearch(searchbox.Text, "");

            HtmlTable table = ProductosTools.ListProductos(lista);


            if (table != null)
            {
                ListProductos.Controls.Add(table);
                ListProductos.Visible = true;
            }
            else
            {
                label.Visible = true;
                label.ForeColor = Color.DarkRed;
                label.Text = "No se encontraron productos que cumplan con la búsqueda";
            }
        }

        // Funcion que se llama para preparar el panel en donde se agrega
        protected void PrepareAddButton_Click1(object sender, EventArgs e)
        {
            PrepareDetailsAdd();
        }

        protected void EditButton_Click(object sender, EventArgs e)
        {
            EditProducto();
        }

        protected void AddButton_Click(object sender, EventArgs e)
        {
            AddProducto();
        }

        private void AddProducto()
        {
            
            try
            {
                
                ProductoLogic.add(double.Parse(taPrice.Text), taCategory.Text, taName.Text);
                label.Visible = true;
                label.ForeColor = Color.Blue;
                label.Text = "Producto agregado satifactoriamente";
            }
            #region manejo de errores
            catch (EntityCouldntBeSaved exception)
            {
                label.Visible = true;
                label.ForeColor = Color.Red;
                label.Text = "No se pudo agregar el producto";
                PanelEditProducto.Visible = true;
                Session.Add("Error", exception);
            }
            catch (FormatException exception)
            {
                label.Visible = true;
                label.ForeColor = Color.DarkRed;
                label.Text = "Precio no valido";
                Session.Add("Error", exception);
                PanelAddProducto.Visible = true;

            }
            catch (Exception exception)
            {
                Session.Add("Error", exception);
                Response.Redirect("../../Views/Home/Error.aspx", true);
            } 
            #endregion

            
           
        }

        
    }
}
